package clang.functions;

import java.util.Vector;

import clang.control.ExecutionThread;
import clang.data.Expression;
import clang.data.VarType;
import clang.data.Variable;

public class FunctionCall implements Expression {

	protected String name;
	protected Vector<Expression> parameters = new Vector<Expression>();
	protected Function funcRef = null;
	
	public FunctionCall(String funcName)
	{
		this.name = funcName;
	}
	
	public FunctionCall(String funcName, Vector<Expression> params)
	{
		this.name = funcName;
		this.parameters = params;
	}
	
	public void addParameter(Expression e)
	{
		parameters.add(e);
	}
	
	public String getName() {
		return name;
	}

	@Override
	public VarType getType() {
		if(funcRef == null) funcRef = ExecutionThread.get().findFunction(this);
		if(funcRef != null)
			return funcRef.getSignature().getReturnType();
		else
			return VarType.VOID;
	}

	@Override
	public Variable calculate() throws Exception {
		if(funcRef == null) funcRef = ExecutionThread.get().findFunction(this);
		
		if(funcRef != null)
			return funcRef.execute(parameters);
		else
			throw new Exception("Unknown function or invalid parameters : " + name);
	}
	
	public Function getFunction() {
		if(funcRef == null) funcRef = ExecutionThread.get().findFunction(this);
		return funcRef;
	}

	@Override
	public void setData(Expression e) throws Exception {
		throw new Exception("Can't assign to function call!");
	}

	@Override
	public void execute() throws Exception {
		ExecutionThread.get().executeCall(this);
	}
	
	public void invalidate() {
		funcRef = null;
	}
	
	public String toString() {
		return "FCALL : " + getType() + " " + name + " (" + parameters.size() + " params)";
	}
}
